//
//  DemoFile.m
//  ocdemo
//
//  Created by JIENING ZHANG on 2019/6/12.
//  Copyright © 2019 JIENING ZHANG. All rights reserved.
//
#import "DemoFile.h"
#import "NSObject+GGJson.h"
#import "NSString+GGJson.h"
#import "DemoNSCoding.h"

@implementation DemoFile

+ (void)depthFirstLoop:(NSString *)dirPath fileManager:(NSFileManager *)fileManager {
    
    if(! fileManager) {
        fileManager = [NSFileManager defaultManager];
    }
    
    // 文件/目录 路径是否存在，isDir 带回 是否是 目录
    BOOL isDir = NO;
    BOOL isExist = [fileManager fileExistsAtPath:dirPath isDirectory:&isDir];
    if(! isExist) {
        NSLog(@"file/dir not exist : %@", dirPath);
        return;
    }
    
    NSError *err;
    
    if(isDir) {
        
        NSLog(@"DF, dir : %@", dirPath);
        
        // 获取目录下的文件/目录列表
        NSArray *contentOfFolder = [fileManager contentsOfDirectoryAtPath:dirPath error:&err];
        
        for(NSString *filename in contentOfFolder) {
            
            NSString *subFilePath = [NSString stringWithFormat:@"%@/%@", dirPath, filename];
            
            [DemoFile depthFirstLoop:subFilePath fileManager:fileManager];
        }
        
    } else {
        NSLog(@"DF, file : %@", dirPath);
    }
}

+ (void)breadthFirst:(NSString *)dirPath fileManager:(NSFileManager *)fileManager {
    if(! fileManager) {
        fileManager = [NSFileManager defaultManager];
    }
    
    // 文件/目录 路径是否存在，isDir 带回 是否是 目录
    BOOL isDir = NO;
    BOOL isExist = [fileManager fileExistsAtPath:dirPath isDirectory:&isDir];
    if(! isExist) {
        NSLog(@"file/dir not exist : %@", dirPath);
        return;
    }
    
    NSError *err;
    
    if(isDir) {
        
        NSArray *contentOfFolder = [fileManager contentsOfDirectoryAtPath:dirPath error:&err];
        
        NSMutableArray *dirArr =  [NSMutableArray array];
        for(NSString *filename in contentOfFolder) {
            
            NSString *subFilePath = [NSString stringWithFormat:@"%@/%@", dirPath, filename];
            
            isExist = [fileManager fileExistsAtPath:subFilePath isDirectory:&isDir];
            if(isDir) {
                NSLog(@"WF, dir : %@", subFilePath);
                [dirArr addObject:subFilePath];
            } else {
                NSLog(@"WF, file : %@", subFilePath);
            }
        }
        
        for(NSString *subDirPath in dirArr) {
            [DemoFile breadthFirst:subDirPath fileManager:fileManager];
        }
        
    } else {
        NSLog(@"WF, file : %@", dirPath);
    }
}

+ (void)textFileRead:(NSString *)filePath {
    NSError *error ;
    NSStringEncoding encoding;
    

    //第一种方法： NSFileManager实例方法读取数据
    NSFileManager* fm = [NSFileManager defaultManager];
    NSData* data = [[NSData alloc] init];
    data = [fm contentsAtPath:filePath];
    if(data){
        NSLog(@"read using NSFileManager contentsAtPath ：%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
    } else {
        NSLog(@"fail read using NSFileManager contentsAtPath ： %@",filePath);
    }
    
    //第二种方法： NSData类方法读取数据
    data = [NSData dataWithContentsOfFile:filePath];
    if(data){
        NSLog(@"read using NSData dataWithContentsOfFile ：%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
    } else {
        NSLog(@"fail read using NSData dataWithContentsOfFile ： %@",filePath);
    }
    
    //第三种方法： NSString类方法读取内容, 指定编码集 UTF8
    NSString* content = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&error];
    if (error == nil) {
        NSLog(@"read using NSString stringWithContentsOfFile: encoding: error: %@", content);
    } else {
        NSLog(@"stringWithContentsOfFile fail, error %@", error);
    }
    
    // NSString类方法读取内容, 探测编码集
    content = [NSString stringWithContentsOfFile:filePath usedEncoding:&encoding error:&error];
    if (error == nil) {
        
        NSLog(@"read using NSString stringWithContentsOfFile: usedEncoding: error: : %@", content);
        NSLog(@"编码格式 %lu", encoding); //如utf-8编码的会得到4
        
    } else {
        NSLog(@"stringWithContentsOfFile fail, error %@", error);
    }
    
    
    //第四种方法： NSFileHandle实例方法读取内容
    NSFileHandle* fh = [NSFileHandle fileHandleForReadingAtPath:filePath];
    data = [fh readDataToEndOfFile];
    if(data){
        NSLog(@"read using NSFileHandle readDataToEndOfFile ：\n%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
    } else {
        NSLog(@"fail read using NSFileHandle readDataToEndOfFile ： %@",filePath);
    }
    
    //第五种方法：NSInputStream，逐字符读取，按行提取 NSString
    // 初始化 NSInputStream
    NSInputStream *instream = [[NSInputStream alloc]initWithFileAtPath:filePath];
    uint8_t buf1[1];
    uint8_t cStringBuffer[1024*16];
    int index = 0;
    NSInteger readCount = 0;
    
    // 打开 NSInputStream 对象
    [instream open];
    
    // 循环读取
    while([instream hasBytesAvailable]) {
        
        // 逐字符读取
        readCount = [instream read:buf1 maxLength:1];
        if(buf1[0] == '\n') {
            
            // 读取到回车符号，c字符buffer中写入终止符号 0
            cStringBuffer[index] =  0;
            
            // 按行提取 NSString
            NSString *lineStr = [NSString stringWithCString:((char *)cStringBuffer) encoding:NSUTF8StringEncoding];
            NSLog(@"lineStr:%@", lineStr);
            
            index = -1;
        } else {
            
            // 读取到 非 回车符号，读取的字符写入c字符buffer
            cStringBuffer[index] = buf1[0];
        }
        
        ++ index;
    }
    // 关闭 NSInputStream 对象
    [instream close];
}

+ (void)textFileWrite:(NSString *)filePath {
    
    NSString *string = @"水调歌头·明月几时有 \n\
苏轼 \n\
丙辰中秋，欢饮达旦，大醉，作此篇，兼怀子由。\n\
\n\
明月几时有？把酒问青天。\n\
不知天上宫阙，今夕是何年。\n\
我欲乘风归去，又恐琼楼玉宇，高处不胜寒。\n\
起舞弄清影，何似在人间。\n\
\n\
转朱阁，低绮户，照无眠。\n\
不应有恨，何事长向别时圆？\n\
人有悲欢离合，月有阴晴圆缺，此事古难全。\n\
但愿人长久，千里共婵娟。";
    
    NSError *error ;
    
    // NSString writeToFile 写入
    BOOL isWriteString =[string writeToFile:filePath atomically:YES encoding:NSUTF8StringEncoding error:&error];
    if (isWriteString) {
        NSLog(@"NSString writeToFile 文件写入成功 %@", filePath);
    } else {
        NSLog(@"NSString writeToFile 文件写入失败 %@", error);
    }

}

+ (void)binFileRead {
    
    // 账目记录:
    //  账目创建时间戳(主键),   int64_t
    //  账目发生时间戳，        int64_t
    //  金额,                 double
    //  币种,                 uint8_t
    //  分类数，               uint8_t
    //  分类1,                uint64_t
    //  分类2,                uint64_t
    //  ...,
    //  分类n,                uint64_t
    //  comment字符串（utf8）字节数, uint32_t
    //  comment字符串（utf8）字节
    
    // 从文件 读取 NSData
    NSArray *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
    NSString *documentsPath = [docPath objectAtIndex:0];
    NSString *binFilePath = [documentsPath stringByAppendingString:@"/test.mcbin"];
    
    NSData *dataFromFile = [NSData dataWithContentsOfFile:binFilePath];
    if(!dataFromFile || [dataFromFile length]==0) {
        NSLog(@"二进制 文件读取失败 %@", binFilePath);
        return;
    }
    
    NSInteger nSize = [dataFromFile length];
    
    NSLog(@"二进制 文件读取成功，长度%lu, %@", nSize, binFilePath);
    
    // 从NSData 依次 拷贝出 账目的 各个 信息变量
    
    char* pBuffer = (char*)[dataFromFile bytes];
    char* pRead = pBuffer;
    
    int64_t createTS;
    memcpy(&createTS, pRead, sizeof(createTS));
    pRead += sizeof(createTS);
    
    int64_t accountTS;
    memcpy(&accountTS, pRead, sizeof(accountTS));
    pRead += sizeof(accountTS);
    
    double accountNum;
    memcpy(&accountNum, pRead, sizeof(accountNum));
    pRead += sizeof(accountNum);
    
    uint8_t accountMK;
    memcpy(&accountMK, pRead, sizeof(accountMK));
    pRead += sizeof(accountMK);
    
    uint8_t accountCategoryNum;
    memcpy(&accountCategoryNum, pRead, sizeof(accountCategoryNum));
    pRead += sizeof(accountCategoryNum);
    
    NSMutableArray *cateArr = [NSMutableArray array];
    for(uint8_t loop=0; loop<accountCategoryNum;++loop) {
        uint64_t cate;
        memcpy(&cate, pRead, sizeof(cate));
        pRead += sizeof(cate);
        
        [cateArr addObject:@(cate)];
    }
    
    uint32_t commentStrLen;
    memcpy(&commentStrLen, pRead, sizeof(commentStrLen));
    pRead += sizeof(commentStrLen);
    
    NSUInteger loc = pRead - pBuffer;
    NSUInteger len = nSize - loc;
    NSData *commentStrData = [dataFromFile subdataWithRange:NSMakeRange(loc, len)];
    
    NSString *commentStr = [[NSString alloc] initWithData:commentStrData encoding:NSUTF8StringEncoding];
    
    // 把账目的各变量打印出来看
    
    NSMutableString *mstr = [NSMutableString string];
    
    [mstr appendFormat:@"账目创建时间戳(主键) %lld, ", createTS];
    [mstr appendFormat:@"账目发生时间戳 %lld, ", accountTS];
    [mstr appendFormat:@"金额 %.2f, ", accountNum];
    [mstr appendFormat:@"币种 %d, ", accountMK];
    [mstr appendFormat:@"分类数 %d, ", accountCategoryNum];
    
    for(NSNumber *cateNum in cateArr) {
        [mstr appendFormat:@"分类 %ld, ", cateNum.integerValue];
    }
    
    [mstr appendFormat:@"comment字符串（utf8）字节数 %u, ", commentStrLen];
    [mstr appendFormat:@"comment字符串（utf8）%@, ", commentStr];
    
    NSLog(@"get account info from bin: %@", mstr);

}

+ (void)binFileWrite {
    
    // 账目记录:
    //  账目创建时间戳(主键),   int64_t
    //  账目发生时间戳，        int64_t
    //  金额,                 double
    //  币种,                 uint8_t
    //  分类数，               uint8_t
    //  分类1,                uint64_t
    //  分类2,                uint64_t
    //  ...,
    //  分类n,                uint64_t
    //  comment字符串（utf8）字节数, uint32_t
    //  comment字符串（utf8）字节
    
    // 把账目的各变量塞进 NSMutableData
    NSMutableData *data2Write = [NSMutableData data];
    
    int64_t createTS = [[NSDate date] timeIntervalSince1970];
    int64_t accountTS = createTS;
    double accountNum = 32.5;
    uint8_t accountMK = 1;
    uint8_t accountCategoryNum = 3;
    uint64_t accountCategory1 = 110;
    uint64_t accountCategory2 = 30000;
    uint64_t accountCategory3 = 5600000L;
    
    NSString *commentStr = @"午饭，鸡腿+关东煮，挣了800积分";
    NSData *commentStrData = [commentStr dataUsingEncoding:NSUTF8StringEncoding];
    uint32_t commentStrLen = (uint32_t)[commentStrData length];
    
    [data2Write appendBytes:&createTS length:sizeof(createTS)];
    [data2Write appendBytes:&accountTS length:sizeof(accountTS)];
    [data2Write appendBytes:&accountNum length:sizeof(accountNum)];
    [data2Write appendBytes:&accountMK length:sizeof(accountMK)];
    
    [data2Write appendBytes:&accountCategoryNum length:sizeof(accountCategoryNum)];
    [data2Write appendBytes:&accountCategory1 length:sizeof(accountCategory1)];
    [data2Write appendBytes:&accountCategory2 length:sizeof(accountCategory2)];
    [data2Write appendBytes:&accountCategory3 length:sizeof(accountCategory3)];
    
    [data2Write appendBytes:&commentStrLen length:sizeof(commentStrLen)];
    [data2Write appendBytes:[commentStrData bytes] length:commentStrLen];
    
    // 把账目的各变量打印出来看
    NSMutableString *mstr = [NSMutableString string];
    [mstr appendFormat:@"账目创建时间戳(主键) %lld, ", createTS];
    [mstr appendFormat:@"账目发生时间戳 %lld, ", accountTS];
    [mstr appendFormat:@"金额 %.2f, ", accountNum];
    [mstr appendFormat:@"币种 %d, ", accountMK];
    
    [mstr appendFormat:@"分类数 %d, ", accountCategoryNum];
    [mstr appendFormat:@"分类 %llu, ", accountCategory1];
    [mstr appendFormat:@"分类 %llu, ", accountCategory2];
    [mstr appendFormat:@"分类 %llu, ", accountCategory3];
    
    [mstr appendFormat:@"comment字符串（utf8）字节数 %u, ", commentStrLen];
    [mstr appendFormat:@"comment字符串（utf8）%@, ", commentStr];
    
    NSLog(@"about 2 set account info into bin: %@", mstr);
    
    // 把 NSMutableData 写入文件
    NSArray *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
    NSString *documentsPath = [docPath objectAtIndex:0];
    NSString *binFilePath = [documentsPath stringByAppendingString:@"/test.mcbin"];
    
    NSLog(@"before 写二进制文件，长度%lu, %@", (unsigned long)[data2Write length], binFilePath);
    
    BOOL writeRes = [data2Write writeToFile:binFilePath atomically:YES];
    if(writeRes) {
        NSLog(@"二进制 文件写入成功 %@", binFilePath);
    } else {
        NSLog(@"二进制 文件写入失败 %@", binFilePath);
    }
}

+ (void)writePlist {
    // 以下列出的类型才能使用plist文件存储:
    // NSArray; NSMutableArray; NSDictionary; NSMutableDictionary; NSData; NSMutableData; NSString; NSMutableString; NSNumber; NSDate;
    
    NSArray *month = @[
                       @"January",
                       @"February",
                       @"March",
                       @"April",
                       @"May",
                       @"June",
                       @"July",
                       @"August",
                       @"September",
                       @"October",
                       @"November",
                       @"December",
                       ];
    
    NSDictionary *monthDic = @{
                               @"January" :     @(31),
                               @"February" :    @(28),
                               @"March" :       @(31),
                               @"April" :       @(30),
                               @"May" :         @(31),
                               @"June" :        @(30),
                               @"July" :        @(31),
                               @"August" :      @(31),
                               @"September" :   @(30),
                               @"October" :     @(31),
                               @"November" :    @(30),
                               @"December" :    @(31),
                               };
    
    NSMutableDictionary *dic2Write = [NSMutableDictionary dictionary];
    dic2Write[@"array"] = month;
    dic2Write[@"arrayMutable"] = [NSMutableArray arrayWithArray:month];
    dic2Write[@"dic"] = monthDic;
    dic2Write[@"dicMutable"] = [NSMutableDictionary dictionaryWithDictionary:monthDic];
    dic2Write[@"string"] = @"年月日";
    dic2Write[@"stringMutable"] = [NSMutableString stringWithFormat:@"年月日"];
    dic2Write[@"number"] = @(3.1416);
    dic2Write[@"bool"] = @(YES);
    dic2Write[@"date"] = [NSDate date];
    
    // 如果有不兼容的部分，writeToFile 返回NO，写入不会成功
    //dic2Write[@"incompatible"] = [DemoFile new];
    
    //temp目录
    NSString *tempPath = NSTemporaryDirectory();
    NSString *plistPath = [tempPath stringByAppendingString:@"/demo.plist"];
    
    BOOL writeRes = [dic2Write writeToFile:plistPath atomically:YES];
    if(writeRes) {
        NSLog(@"写plist文件成功 %@", plistPath);
    } else {
        NSLog(@"写plist文件失败 %@", plistPath);
    }
}

+ (void)readFromPlist {
    // 以下列出的类型才能使用plist文件存储:
    // NSArray; NSMutableArray; NSDictionary; NSMutableDictionary; NSData; NSMutableData; NSString; NSMutableString; NSNumber; NSDate;
    // property list objects (NSString, NSData, NSDate, NSNumber, NSArray, or NSDictionary objects).
    
    //temp目录
    NSString *tempPath = NSTemporaryDirectory();
    NSString *plistPath = [tempPath stringByAppendingString:@"/demo.plist"];
    
    NSDictionary *dicFromFile = [NSDictionary dictionaryWithContentsOfFile:plistPath];
    
    //NSError *error;
    //NSDictionary *dicFromFile =[NSDictionary dictionaryWithContentsOfURL:[NSURL fileURLWithPath:plistPath] error:&error];
    
    if(! dicFromFile) {
        NSLog(@"读取plist文件失败 %@", plistPath);
        return;
    }
    
    for(NSString *key in dicFromFile) {
        id val = dicFromFile[key];
        NSLog(@"readFromPlist, %@ -> %@, %@", key, NSStringFromClass([val class]), val);
        
        // NSDictionary dictionaryWithContentsOfFile 方法的说明有这样一句
        // The objects contained by this dictionary are immutable, even if the dictionary is mutable.
        // 构建出来的字典包含的对象都是不可变的
        // 但是为啥检测都是可变的呢（模拟器 iphoneXR iOS 12.2）？苹果变了实现没有更新说明吗？
        
        if([val isKindOfClass:[NSMutableArray class]]) {
            NSLog(@"readFromPlist, %@ -> NSMutableArray", key);
        }
        if([val isKindOfClass:[NSMutableDictionary class]]) {
            NSLog(@"readFromPlist, %@ -> NSMutableDictionary", key);
        }
        if([val isKindOfClass:[NSMutableString class]]) {
            NSLog(@"readFromPlist, %@ -> NSMutableString", key);
        }
    }
}

+ (void)writeJson {
    
    NSArray *month = @[
                       @"January",
                       @"February",
                       @"March",
                       @"April",
                       @"May",
                       @"June",
                       @"July",
                       @"August",
                       @"September",
                       @"October",
                       @"November",
                       @"December",
                       ];
    
    NSDictionary *monthDic = @{
                               @"January" :     @(31),
                               @"February" :    @(28),
                               @"March" :       @(31),
                               @"April" :       @(30),
                               @"May" :         @(31),
                               @"June" :        @(30),
                               @"July" :        @(31),
                               @"August" :      @(31),
                               @"September" :   @(30),
                               @"October" :     @(31),
                               @"November" :    @(30),
                               @"December" :    @(31),
                               };
    
    NSMutableDictionary *dic2Write = [NSMutableDictionary dictionary];
    dic2Write[@"array"] = month;
    dic2Write[@"arrayMutable"] = [NSMutableArray arrayWithArray:month];
    dic2Write[@"dic"] = monthDic;
    dic2Write[@"dicMutable"] = [NSMutableDictionary dictionaryWithDictionary:monthDic];
    dic2Write[@"string"] = @"年月日";
    dic2Write[@"stringMutable"] = [NSMutableString stringWithFormat:@"年月日"];
    dic2Write[@"number"] = @(3.1416);
    dic2Write[@"bool"] = @(YES);
    
    // 如果有不兼容的部分，组装json字符串会失败
    //dic2Write[@"date"] = [NSDate date];
    
    // 如果有不兼容的部分，组装json字符串会失败
    //dic2Write[@"incompatible"] = [DemoFile new];
    
    //temp目录
    NSString *tempPath = NSTemporaryDirectory();
    NSString *jsonPath = [tempPath stringByAppendingString:@"/demo.json"];
    
    NSString *jsonStr = [dic2Write ggJsonStringPrettty];
    if([jsonStr length]==0) {
        NSLog(@"组装json字符串失败 %@", dic2Write);
        return;
    }
    
    NSError *err = nil;
    BOOL writeRes = [jsonStr writeToFile:jsonPath atomically:YES encoding:NSUTF8StringEncoding error:&err];
    if(writeRes) {
        NSLog(@"写json文件成功 %@", jsonPath);
    } else {
        NSLog(@"写json文件失败 %@, %@", jsonPath, err);
    }
}

+ (void)readFromJson {
    
    //temp目录
    NSString *tempPath = NSTemporaryDirectory();
    NSString *jsonPath = [tempPath stringByAppendingString:@"/demo.json"];
    
    // NSString类方法读取内容, 指定编码集 UTF8
    NSError *err = nil;
    NSString* jsonStr = [NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:&err];
    if (err) {
        NSLog(@"stringWithContentsOfFile fail, %@, error %@", jsonPath, err);
        return;
    }
    
    id jsonObj = [jsonStr ggJsonObj];
    

    if(! [jsonObj isKindOfClass:[NSDictionary class]]) {
        NSLog(@"从json字符串构建 NSDictionary 对象失败");
        return;
    }
    
    NSDictionary *dicFromFile = (NSDictionary *)jsonObj;
    
    for(NSString *key in dicFromFile) {
        id val = dicFromFile[key];
        NSLog(@"readFromJson, %@ -> %@, %@", key, NSStringFromClass([val class]), val);
        
        // NSDictionary dictionaryWithContentsOfFile 方法的说明有这样一句
        // The objects contained by this dictionary are immutable, even if the dictionary is mutable.
        // 构建出来的字典包含的对象都是不可变的
        // 但是为啥检测都是可变的呢（模拟器 iphoneXR iOS 12.2）？苹果变了实现没有更新说明吗？
        
        if([val isKindOfClass:[NSMutableArray class]]) {
            NSLog(@"readFromJson, %@ -> NSMutableArray", key);
        }
        if([val isKindOfClass:[NSMutableDictionary class]]) {
            NSLog(@"readFromJson, %@ -> NSMutableDictionary", key);
        }
        if([val isKindOfClass:[NSMutableString class]]) {
            NSLog(@"readFromJson, %@ -> NSMutableString", key);
        }
    }
}

+ (void)writeNSCodingObject {

    DemoNSCoding *root = [DemoNSCoding new];
    root.name = @"root";
    
    DemoNSCoding *left = [DemoNSCoding new];
    left.name = @"left";
    
    DemoNSCoding *center = [DemoNSCoding new];
    center.name = @"center";
    
    DemoNSCoding *right = [DemoNSCoding new];
    right.name = @"right";
    
    root.binData = [@"data from String" dataUsingEncoding:NSUTF8StringEncoding];
    root.children = @[left, center, right];
    root.info = @{@"depth" : @"2"};
    
    NSLog(@"writeNSCodingObject, root: %@ ", root);
    
    NSString *tempPath = NSTemporaryDirectory();
    NSString *ocobjPath = [tempPath stringByAppendingString:@"/demo.ocobj"];
    
    BOOL archiveRes = [NSKeyedArchiver archiveRootObject:root toFile:ocobjPath];
    if(archiveRes) {
        NSLog(@"oc对象持久化到文件成功 %@", ocobjPath);
    } else {
        NSLog(@"oc对象持久化到文件失败 %@", ocobjPath);
    }
}

+ (void)readNSCodingObject {
    NSString *tempPath = NSTemporaryDirectory();
    NSString *ocobjPath = [tempPath stringByAppendingString:@"/demo.ocobj"];
    
    id objFromFile = [NSKeyedUnarchiver unarchiveObjectWithFile:ocobjPath];
    if(! objFromFile) {
        NSLog(@"从文件读取oc对象失败 %@", ocobjPath);
        return;
    }
    
    NSLog(@"从文件读取oc对象成功 %@, %@", ocobjPath, objFromFile);
}

+ (void)demoLogic {
    
    //获取Documents文件夹目录,第一个参数是说明获取Doucments文件夹目录，第二个参数说明是在当前应用沙盒中获取，所有应用沙盒目录组成一个数组结构的数据存放
    NSArray *docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);
    NSString *documentsPath = [docPath objectAtIndex:0];
    //NSLog(@"Documents目录：%@",documentsPath);
    
    //获取Cache目录
    NSArray *cacPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
    NSString *cachePath = [cacPath objectAtIndex:0];
    //NSLog(@"Cache目录：%@",cachePath);
    
    //Library目录
    NSArray *libsPath = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
    NSString *libPath = [libsPath objectAtIndex:0];
    //NSLog(@"Library目录：%@",libPath);
    
    //temp目录
    NSString *tempPath = NSTemporaryDirectory();
    //NSLog(@"temp目录：%@",tempPath);
    
    
    // 深度优先 递归遍历目录
    [DemoFile depthFirstLoop:libPath fileManager:nil];
    // 广度优先 递归遍历目录
    [DemoFile breadthFirst:libPath fileManager:nil];

    
    NSString *textFilePath = [documentsPath stringByAppendingString:@"/text.txt"];
    
    // 文本文件读取
    [DemoFile textFileRead:textFilePath];
    
    // 文本文件写出
    [DemoFile textFileWrite:textFilePath];
    
    // 二进制文件写出
    [DemoFile binFileWrite];
    
    // 二进制文件读取Read
    [DemoFile binFileRead];
    
    // plist 文件读写
    // property list objects (NSString, NSData, NSDate, NSNumber, NSArray, or NSDictionary objects).
    [DemoFile writePlist];
    [DemoFile readFromPlist];
    
    // json 文件读写
    // (NSString, NSNumber, NSArray, or NSDictionary objects).
    [DemoFile writeJson];
    [DemoFile readFromJson];
    
    // 对象文件读写
    [DemoFile writeNSCodingObject];
    [DemoFile readNSCodingObject];
}

@end
